home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / at.c < prev    next >
C/C++ Source or Header  |  1993-11-18  |  8KB  |  376 lines

  1. /*      Timed execution routine. Starts a timer and executes a sequence
  2.  *    of commands when expired.
  3.  *
  4.  *    Added by IW0CNB - Feb 1992
  5.  *  'at mm' format added by WG7J - 920805
  6.  *  
  7.  *      Added by WA7TAS Oct 1992:
  8.  *
  9.  *         'at k' command
  10.  *
  11.  *         Repeating AT command
  12.  *           - bug fix June 2, 1993
  13.  *           - merged changes into Johan's new code June 14, 1993
  14.  *
  15.  */
  16. #include <time.h>
  17. #ifdef MSDOS
  18. #include <dos.h>
  19. #endif
  20. #include "global.h"
  21. #include "timer.h"
  22. #include "proc.h"
  23. #include "cmdparse.h"
  24. #include "socket.h"
  25.  
  26. void atcmd __ARGS((char *command));
  27.  
  28. /* List of events; We keep note of all timer processes generated by the 
  29.  * at command.
  30.  */
  31. struct at_list {
  32.     struct at_list *next;    /* Linked-list pointer */
  33.     struct timer *at_timer;
  34.     char   recur[10];    /* used in recursive 'at' commands*/
  35.     unsigned int id;    /* numerical 'id' of this 'at' */
  36. };
  37.  
  38. #define    NULLATLIST    (struct at_list *)0
  39.  
  40. static struct at_list *Head_loe = NULLATLIST;    /* Head of List Of Events */
  41. static int id=1;        /* next 'at' assigned gets this number */
  42.  
  43. int
  44. doat(argc,argv,p)
  45. int argc;
  46. char *argv[];
  47. void *p;
  48. {
  49.     struct date *exp_date;
  50.     struct time *exp_time;
  51.     struct timer *t;
  52.  
  53.     char *cp,*dp;
  54.     unsigned int tid;
  55.     int i,notf;
  56.     time_t nowtime;
  57.     unsigned long time1;
  58.     struct tm tm;
  59.     extern struct timer *Timers;
  60.     struct at_list *loe,*pp;    /* List of events */
  61.     char *Errmsg = "Usage:\nat yymmddhhmm <cmd>\nat hhmm <cmd>\nat mm <cmd>\nat now+hhmm <cmd>\nat k <id num> <id num> ...\n";
  62.  
  63.     if(argc < 2){        /* Print list of pending at commands */
  64.             tputs("List of events:\n");
  65.  
  66.         for(t = Timers;t != NULLTIMER;t = t->next){
  67.             if(t->func == (void (*)())atcmd){
  68.             loe=Head_loe;
  69.             while(loe!=NULLATLIST) {
  70.                 if(loe->at_timer == t) break;
  71.                 loe=loe->next;
  72.             }
  73.             time(&nowtime);
  74.             nowtime = (time_t)(read_timer(t) / 1000L + (unsigned long)nowtime);
  75.             cp = ctime(&nowtime);
  76.             rip(cp);
  77.             dp = strchr(t->arg,'|');
  78.             *dp = 0;
  79.             tprintf("At: %s - ID: %5u - Command: %s\n",cp,loe->id,t->arg);
  80.             *dp = '|';
  81.            }
  82.         }
  83.             return 0;
  84.     }
  85.  
  86.     if(argc < 3){
  87.             tputs(Errmsg);
  88.             return 0;
  89.     }
  90.  
  91.     if(argv[1][0]=='k') {
  92.        i=2;
  93.        while(i<argc) {
  94.         tid=atoi(argv[i]);
  95.            if(strlen(argv[i])>5 || tid==0 || atol(argv[i])>65535) {
  96.             tprintf("Invalid ID #.\n");
  97.             return 0;
  98.         }
  99.         loe=Head_loe;
  100.         notf=1;
  101.         while(loe!=NULLATLIST) {
  102.             if(loe->id==tid) {
  103.                 stop_timer(loe->at_timer);
  104.                 free(loe->at_timer->arg);
  105.                 free(loe->at_timer);
  106.                 if(loe == Head_loe) {
  107.                     Head_loe=loe->next;
  108.                 }
  109.                 else {
  110.                     pp->next=loe->next;
  111.                 }
  112.                 free(loe);
  113.                 tprintf("at id: %u--Killed.\n",tid);
  114.                 notf=0;
  115.                 break;
  116.             }
  117.             pp=loe;
  118.             loe=loe->next;
  119.         }
  120.         if(notf) tprintf("  ID %u not found.\n",tid);
  121.         i++;
  122.         }
  123.         return 0;
  124.     }
  125.     exp_date = (struct date *)mallocw(sizeof(struct date));
  126.     exp_time = (struct time *)mallocw(sizeof(struct time));
  127.  
  128.     cp=mallocw(5);
  129.  
  130.     switch(strlen(argv[1])){
  131.        case 10:    /* Full date and time given */
  132.         cp[0]=argv[1][0];
  133.         cp[1]=argv[1][1];
  134.         cp[2]='\0';
  135.     
  136.         exp_date->da_year = 1900 + atoi(cp);
  137.         if(exp_date->da_year > 1999) goto error;
  138.  
  139.         cp[0]=argv[1][2];
  140.         cp[1]=argv[1][3];
  141.         cp[2]='\0';
  142.  
  143.         exp_date->da_mon = (char)atoi(cp);
  144.         if(exp_date->da_mon > 12) goto error;
  145.  
  146.         cp[0]=argv[1][4];
  147.         cp[1]=argv[1][5];
  148.         cp[2]='\0';
  149.  
  150.         exp_date->da_day = (char)atoi(cp);
  151.         if(exp_date->da_day > 31) goto error;
  152.  
  153.         cp[0]=argv[1][6];
  154.         cp[1]=argv[1][7];
  155.         cp[2]='\0';
  156.  
  157.         exp_time->ti_hour = (char)atoi(cp);
  158.         if(exp_time->ti_hour > 23) goto error;
  159.  
  160.         cp[0]=argv[1][8];
  161.         cp[1]=argv[1][9];
  162.         cp[2]='\0';
  163.  
  164.         exp_time->ti_min = (char)atoi(cp);
  165.         if(exp_time->ti_min > 59) goto error;
  166.  
  167.         exp_time->ti_sec = 0;
  168.         exp_time->ti_hund = 0;
  169.  
  170.         time(&nowtime);
  171.         time1 = (unsigned long)dostounix(exp_date,exp_time);
  172.         if(time1 < (unsigned long)nowtime) goto error;
  173.  
  174.         break;
  175.  
  176.        case 4:  /* Only time given, so apply current date */
  177.         getdate(exp_date);
  178.         cp[0]=argv[1][0];
  179.         cp[1]=argv[1][1];
  180.         cp[2]='\0';
  181.  
  182.         exp_time->ti_hour = (char)atoi(cp);
  183.         if(exp_time->ti_hour > 23) goto error;
  184.  
  185.         cp[0]=argv[1][2];
  186.         cp[1]=argv[1][3];
  187.         cp[2]='\0';
  188.  
  189.         exp_time->ti_min = (char)atoi(cp);
  190.         if(exp_time->ti_min > 59) goto error;
  191.  
  192.         exp_time->ti_sec = 0;
  193.         exp_time->ti_hund = 0;
  194.  
  195.         time(&nowtime);
  196.         time1 = (unsigned long)dostounix(exp_date,exp_time);
  197.         if(time1 <= (unsigned long)nowtime){ /* Requested time has passed */
  198.             time1 += 86400L;        /* So book him for tomorrow */
  199.         }
  200.         break;
  201.  
  202.  
  203.        case 2:  /* Only minutes given, so apply current time & date - WG7J */
  204.         tm.tm_min = (char)atoi(argv[1]);
  205.         if(tm.tm_min > 59) goto error;
  206.  
  207.         /* get today's date */
  208.         getdate(exp_date);
  209.         tm.tm_year = exp_date->da_year - 1900;
  210.         tm.tm_mday = exp_date->da_day;
  211.         tm.tm_mon = exp_date->da_mon - 1;
  212.  
  213.         /* get current time */
  214.         gettime(exp_time);
  215.         tm.tm_hour = exp_time->ti_hour;
  216.         /* if we're already past the minute, do it next hour ! */
  217.         if(exp_time->ti_min > tm.tm_min)
  218.             tm.tm_hour++;
  219.  
  220.         /* now adjust this for day boundaries, etc. */
  221.         tm.tm_sec = 0;
  222.         tm.tm_isdst = 0;
  223.         time1 = mktime(&tm);
  224.         time(&nowtime);
  225.         break;
  226.  
  227.        case 8:    /* now+hhmm given */
  228.         strncpy(cp,argv[1],4);
  229.         cp[4]='\0';
  230.         if(strcmp(cp,"now+") != 0) goto error;
  231.  
  232.         cp[0]=argv[1][4];
  233.         cp[1]=argv[1][5];
  234.         cp[2]='\0';
  235.  
  236.         time1=(unsigned long)atoi(cp)*3600L;
  237.  
  238.         cp[0]=argv[1][6];
  239.         cp[1]=argv[1][7];
  240.         cp[2]='\0';
  241.  
  242.         time1+=(unsigned long)atoi(cp)*60L;
  243.         time(&nowtime);
  244.         time1+=(unsigned long)nowtime;
  245.         break;
  246.  
  247.        default:
  248. error:        tprintf(Errmsg);
  249.         free(exp_date);
  250.         free(exp_time);
  251.         free(cp);
  252.         return 0;
  253.  
  254.     } /* switch */
  255.  
  256.     free(cp);
  257.     free(exp_time);
  258.     free(exp_date);
  259.  
  260.     t=(struct timer *)mallocw(sizeof(struct timer));
  261.  
  262.     set_timer(t,(time1 - (unsigned long)nowtime) * 1000L);
  263.     t->state=TIMER_RUN;
  264.     t->func=(void (*)())atcmd;
  265.     t->arg=(char *)mallocw(strlen(argv[2])+12); /*crh*/
  266.     sprintf(t->arg,"%s|%d",argv[2],id);
  267.  
  268.     /* Add the new timer to the head of List Of Events */
  269.     loe=(struct at_list *)mallocw(sizeof(struct at_list));
  270. /*
  271.  * if timer is recursive, set at_list->recur and tack
  272.  *  the '+' character to the end of the timer argument
  273.  */
  274.     loe->recur[0]=0;
  275.     if(argv[2][strlen(argv[2])-1] == '+') {
  276.         strcpy(loe->recur,argv[1]);
  277.         strcat(t->arg,"+");
  278.     }
  279.     loe->at_timer=t;
  280.     loe->id=id++;
  281. /*
  282.  * start the timer
  283.  */
  284.     start_timer(t);
  285. /*
  286.  * an id of 0 is invalid
  287.  */
  288.     if(id==0) id=1;
  289.     loe->next=Head_loe;
  290.     Head_loe=loe;
  291.  
  292.     return 0;
  293. }
  294.  
  295. struct proc *Aproc;
  296.  
  297. /* Process that actually handles 'at' execution */
  298. void
  299. atproc(int i,void *p1,void *p2)
  300. {
  301.     extern struct cmds DFAR Cmds[];
  302.     char *command;
  303.     struct at_list *loe, *p;
  304.     int recur, id;
  305.     char *pp;
  306.     char cmd[80];
  307.  
  308.     command =  (char *)p1;
  309.  
  310.     log(-1,"AT command: %s",command);
  311. /*
  312.  * check for recursion
  313.  */
  314.     if(command[strlen(command)-1] == '+')
  315.         recur=1;
  316.     else
  317.         recur=0;
  318. /*
  319.  * locate id in command string
  320.  */
  321.     pp = strchr(command,'|');
  322.     *pp++ = 0;
  323.     id = atoi(pp);
  324.  
  325.     /* Free up memory for expired at commands */
  326.     p=Head_loe;
  327.     loe=Head_loe;
  328.     while(loe != NULLATLIST){
  329.         if(loe->at_timer->state == TIMER_EXPIRE){
  330.             if(loe->id != id) continue; /* is this the proper entry? */
  331.             if(recur) {
  332.                 strcpy(cmd,"at ");
  333.                 strcat(cmd,loe->recur);
  334.                 strcat(cmd," \"");
  335.                 strcat(cmd,command);
  336.                 strcat(cmd,"\"");
  337.                 command[strlen(command)-1]=0;
  338.             }
  339.             free(loe->at_timer);    /* Free timer */
  340.             if(loe == Head_loe){
  341.                 Head_loe=loe->next;
  342.                 p=loe->next;
  343.                 free(loe);
  344.                 loe=p;
  345.                 p=Head_loe;
  346.             } else {
  347.                 p->next=loe->next;
  348.                 free(loe);
  349.                 loe=p->next;
  350.             }
  351.             break;  /* exit while loop */
  352.         } else {    /* Not expired, go on */
  353.             if(loe != Head_loe) p=p->next;
  354.             loe=loe->next;
  355.         }
  356.     }
  357.  
  358.     cmdparse(Cmds,command,NULL);    /* Go with requested command */
  359.  
  360.     if(recur) cmdparse(Cmds,cmd,NULL);
  361.  
  362.     free(command);
  363.  
  364. }
  365.  
  366. struct proc *Aproc;
  367.  
  368. /* Function to be called on timer expiration to execute a command */
  369. void
  370. atcmd(command)
  371. char *command;
  372. {
  373.     Aproc = newproc("AT handler",1024,atproc,0,(void *)command,NULL,0);
  374. }
  375.  
  376.